<template>
  <el-dialog v-model="dialogVisible" title="课程资源管理" width="60%" @open="handleOpen" @close="handleClose">
      <el-card shadow="never" class="upload-section">
          <template #header>
              <div class="card-header">
                  <span>上传新资源</span>
              </div>
          </template>
          <el-form :model="uploadData" label-width="80px" class="upload-form">
              <el-row :gutter="20">
                  <el-col :span="10">
                      <el-form-item label="资源名称">
                          <el-input v-model="uploadData.resourceName" placeholder="例如：第一章课件" />
                      </el-form-item>
                  </el-col>
                  <el-col :span="7">
                      <el-form-item label="资源类型">
                          <el-select v-model="uploadData.type" placeholder="请选择类型">
                              <el-option label="视频" value="video" />
                              <el-option label="文档" value="document" />
                          </el-select>
                      </el-form-item>
                  </el-col>
                  <el-col :span="7" class="upload-buttons">
                      <el-upload :auto-upload="false" :show-file-list="false" :on-change="handleFileChange"
                          action="#">
                          <el-button type="primary">选择文件</el-button>
                      </el-upload>
                      <el-button type="success" @click="handleUpload" :loading="uploading">
                          确认上传
                      </el-button>
                  </el-col>
              </el-row>
              <div v-if="uploadData.file" class="file-tip">
                  已选择文件：{{ uploadData.file.name }}
              </div>
          </el-form>
      </el-card>

      <el-divider />

      <div class="resource-list">
          <h3>视频资源</h3>
          <div v-if="videoResources.length > 0">
              <el-row :gutter="16">
                  <el-col v-for="res in videoResources" :key="res.id" :span="8">
                      <el-card shadow="hover" class="resource-card">
                          <div style="font-weight: bold; margin-bottom: 5px;">{{ res.resourceName }}</div>
                          <!-- ✅ 新增：视频播放器 -->
                          <video :src="res.url" controls style="width: 100%; border-radius: 6px;"></video>
                      </el-card>
                  </el-col>
              </el-row>
          </div>
          <el-empty v-else description="暂无视频资源" />

          <h3 style="margin-top: 20px;">文档资源</h3>
          <div v-if="documentResources.length > 0">
              <el-row :gutter="16">
                  <el-col v-for="res in documentResources" :key="res.id" :span="8">
                      <el-card shadow="hover" class="resource-card">
                          <div style="font-weight: bold; margin-bottom: 5px;">{{ res.resourceName }}</div>
                          <canvas :ref="el => registerPdfCanvas(el, res.id)" class="thumbnail-canvas"></canvas>
                          <el-button size="small" type="primary" @click="openFullPdf(res)" style="margin-top: 10px;">
                              查看全文
                          </el-button>
                      </el-card>
                  </el-col>
              </el-row>
          </div>
          <el-empty v-else description="暂无文档资源" />
      </div>

      <template #footer>
          <span class="dialog-footer">
              <el-button @click="dialogVisible = false">关闭</el-button>
          </span>
      </template>
  </el-dialog>
  <!-- ✅ 新增：查看全文弹窗 -->
  <el-dialog v-model="pdfPreviewVisible" :title="`文档预览 - ${currentResourceName}`" width="80%" top="5vh">
      <!-- <div style="text-align: center;">
          <canvas ref="pdfPreviewCanvas"></canvas>
          <div style="margin-top: 12px;">
              <el-button @click="prevPage" :disabled="pdfPage <= 1">上一页</el-button>
              <span style="margin: 0 12px;">第 {{ pdfPage }} / {{ pdfTotalPages }} 页</span>
              <el-button @click="nextPage" :disabled="pdfPage >= pdfTotalPages">下一页</el-button>
              <el-button @click="zoomOut" :disabled="scale <= 0.5">缩小</el-button>
              <el-button @click="zoomIn" :disabled="scale >= 3">放大</el-button>
              <el-button type="primary" @click="downloadPdf" style="margin-left: 10px;">下载PDF</el-button>
          </div>
      </div> -->
      <div ref="pdfContainer" class="pdf-container" @mousedown="handleMouseDown" @mousemove="handleMouseMove"
          @mouseup="handleMouseUp" @mouseleave="handleMouseLeave">
          <canvas ref="pdfPreviewCanvas"></canvas>
      </div>
      <div style="text-align: center; margin-top: 12px;">
          <el-button @click="prevPage" :disabled="pdfPage <= 1">上一页</el-button>
          <span style="margin: 0 12px;">第 {{ pdfPage }} / {{ pdfTotalPages }} 页</span>
          <el-button @click="nextPage" :disabled="pdfPage >= pdfTotalPages">下一页</el-button>
          <el-button @click="zoomOut" :disabled="scale <= 0.5">缩小</el-button>
          <el-button @click="zoomIn" :disabled="scale >= 3">放大</el-button>
          <el-button type="primary" @click="downloadPdf" style="margin-left: 10px;">下载PDF</el-button>
      </div>
  </el-dialog>

</template>

<script setup>
import { ref, reactive, computed, nextTick, shallowRef } from 'vue';
import { useCourseStore } from '@/stores/course.js';
import { ElMessage } from 'element-plus';
import { Document, VideoPlay } from '@element-plus/icons-vue';
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf'
import workerSrc from 'pdfjs-dist/legacy/build/pdf.worker?url'
pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc
// ✅ 新增：为拖动功能创建必要的 ref 和 reactive 变量
const pdfContainer = ref(null); // 引用容器 div
const isDragging = ref(false); // 标记是否正在拖动
const dragStartPosition = reactive({ x: 0, y: 0 }); // 记录拖动开始时鼠标的位置
const initialScrollPosition = reactive({ left: 0, top: 0 }); // 记录拖动开始时容器的滚动位置

const previewPdfUrl = ref('')
// 存储每个文档的 canvas 引用
const currentResourceName = ref('');
const pdfCanvasMap = new Map()
const pdfPreviewCanvas = ref(null)
const pdfPreviewVisible = ref(false)
const pdfDocRef = shallowRef(null)
const pdfPage = ref(1)
const pdfTotalPages = ref(1)
const scale = ref(1.5)
// 注册 canvas 引用
const registerPdfCanvas = (el, id) => {
  // 只注册一次
  if (el && !pdfCanvasMap.has(id)) {
      pdfCanvasMap.set(id, el)
      renderPdfById(id)
  }
}

const handlePdfDialogOpened = async () => {
  try {
      const pdf = await pdfjsLib.getDocument(previewPdfUrl.value).promise
      pdfDocRef.value = pdf
      pdfTotalPages.value = pdf.numPages
      pdfPage.value = 1
      scale.value = 1.5
      await nextTick()
      await renderCurrentPage()
  } catch (err) {
      ElMessage.error('加载 PDF 失败')
  }
}

const renderTaskMap = new Map() // 存每个文档的渲染任务

const renderPdfById = async (id) => {
  const res = documentResources.value.find(r => r.id === id)
  if (!res || !res.url) return

  const canvas = pdfCanvasMap.get(id)
  if (!canvas) return

  // 如果上一个渲染还在，取消它
  const prevTask = renderTaskMap.get(id)
  if (prevTask && !prevTask._internalRenderTask.cancelled) {
      try {
          prevTask.cancel()
      } catch (e) {
          console.warn('取消渲染任务失败', e)
      }
  }

  try {
      const pdf = await pdfjsLib.getDocument(res.url).promise
      const page = await pdf.getPage(1)
      const viewport = page.getViewport({ scale: 1.2 })
      const ctx = canvas.getContext('2d')

      canvas.height = viewport.height
      canvas.width = viewport.width

      const renderTask = page.render({ canvasContext: ctx, viewport })
      renderTaskMap.set(id, renderTask) // 保存当前任务
      await renderTask.promise
  } catch (err) {
      console.error('PDF 渲染失败', err)
  }
}
// const openFullPdf = async (url) => {
//   try {
//     // const loadingTask = pdfjsLib.getDocument({ url });
//     const loadingTask = pdfjsLib.getDocument(url);
//     const pdf = await loadingTask.promise;
//     pdfDocRef.value = pdf;
//     pdfTotalPages.value = pdf.numPages;
//     pdfPage.value = 1;
//     scale.value = 1.5;
//     pdfPreviewVisible.value = true; // 最后打开弹窗
//     await nextTick();
//     await renderCurrentPage();
//   } catch (err) {
//     console.error('查看全文失败:', err);
//     ElMessage.error('加载 PDF 失败，请检查资源链接或跨域设置');
//   }
// };
const openFullPdf = async (resource) => {
  try {
      const loadingTask = pdfjsLib.getDocument(resource.url);
      const pdf = await loadingTask.promise;

      pdfDocRef.value = pdf;
      previewPdfUrl.value = resource.url; // 保存URL给下载功能使用
      currentResourceName.value = resource.resourceName; // 保存文件名

      pdfTotalPages.value = pdf.numPages;
      pdfPage.value = 1;
      scale.value = 1.5;
      pdfPreviewVisible.value = true;

      await nextTick();
      await renderCurrentPage();
  } catch (err) {
      console.error('查看全文失败:', err);
      ElMessage.error('加载 PDF 失败，请检查资源链接或跨域设置');
  }
};

// ✅ 新增：下载PDF的函数
const downloadPdf = () => {
  if (!previewPdfUrl.value) {
      ElMessage.warning('没有可下载的PDF链接');
      return;
  }

  // 1. 创建一个隐藏的<a>标签
  const link = document.createElement('a');
  link.href = previewPdfUrl.value;

  // 2. 设置 download 属性，浏览器会执行下载而不是跳转。
  //    我们使用资源名作为默认文件名。
  link.setAttribute('download', `${currentResourceName.value || 'document'}.pdf`);

  // 3. 将<a>标签添加到页面、触发点击、然后移除
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};



const renderCurrentPage = async () => {
  const pdf = pdfDocRef.value
  if (!pdf) return;
  const pageNum = pdfPage.value
  const canvas = pdfPreviewCanvas.value
  const ctx = canvas.getContext('2d')
  const page = await pdf.getPage(pageNum)
  const viewport = page.getViewport({ scale: scale.value })

  canvas.height = viewport.height
  canvas.width = viewport.width

  console.log('renderCurrentPage', {
      canvas: pdfPreviewCanvas.value,
      pdf: pdfDocRef.value,
      page: pdfPage.value
  })

  await page.render({ canvasContext: ctx, viewport }).promise
}

const nextPage = async () => {
  if (pdfPage.value < pdfTotalPages.value) {
      pdfPage.value++
      await renderCurrentPage()
  }
}

const prevPage = async () => {
  if (pdfPage.value > 1) {
      pdfPage.value--
      await renderCurrentPage()
  }
}

const zoomIn = async () => {
  scale.value = Math.min(scale.value + 0.25, 3)
  await renderCurrentPage()
}

const zoomOut = async () => {
  scale.value = Math.max(scale.value - 0.25, 0.5)
  await renderCurrentPage()
}
/**
* 鼠标按下事件：开始拖动
*/
const handleMouseDown = (event) => {
// 阻止默认的拖动行为，例如拖动图片或选中文本
event.preventDefault();

isDragging.value = true;
// 记录初始位置
dragStartPosition.x = event.pageX;
dragStartPosition.y = event.pageY;
// 记录初始滚动位置
initialScrollPosition.left = pdfContainer.value.scrollLeft;
initialScrollPosition.top = pdfContainer.value.scrollTop;
};

/**
* 鼠标移动事件：执行拖动
*/
const handleMouseMove = (event) => {
if (!isDragging.value) return;
event.preventDefault();

// 计算鼠标移动的距离
const dx = event.pageX - dragStartPosition.x;
const dy = event.pageY - dragStartPosition.y;

// 更新容器的滚动位置
// 核心逻辑：新的滚动位置 = 初始滚动位置 - 鼠标移动距离
pdfContainer.value.scrollLeft = initialScrollPosition.left - dx;
pdfContainer.value.scrollTop = initialScrollPosition.top - dy;
};

/**
* 鼠标松开事件：停止拖动
*/
const handleMouseUp = () => {
isDragging.value = false;
};

/**
* 鼠标离开容器事件：同样停止拖动
*/
const handleMouseLeave = () => {
isDragging.value = false;
};
// 定义props，用于接收父组件传递过来的课程ID
const props = defineProps({
  courseId: {
      type: [String, Number],
      required: true,
  }
});

const courseStore = useCourseStore();
const dialogVisible = ref(false);
const uploading = ref(false);

// 上传表单的数据
const uploadData = reactive({
  resourceName: '',
  type: 'video', // 默认类型
  file: null,    // 存储原始File对象
});

// 从Store中获取资源列表，并用computed保持同步
const courseResources = computed(() => courseStore.courseResources);
// 自动分类视频和文档
const videoResources = computed(() => courseResources.value.filter(r => r.type === 'video'));
const documentResources = computed(() => courseResources.value.filter(r => r.type === 'document'));

// 弹窗打开时，调用接口获取当前课程的资源列表
const handleOpen = () => {
  if (props.courseId) {
      // getCourseDetail action 内部会获取课程资源并更新 state
      courseStore.getCourseDetail(props.courseId);
  }
};

// 重置上传表单
const resetUploadForm = () => {
  uploadData.resourceName = '';
  uploadData.type = 'video';
  uploadData.file = null;
};

// 弹窗关闭时，清空表单
const handleClose = () => {
  resetUploadForm();
};

// 选中文件时的回调
const handleFileChange = (uploadFile) => {
  // 保存原始文件对象，而不是代理对象
  uploadData.file = uploadFile.raw;
};

// 点击“确认上传”按钮
const handleUpload = async () => {
  if (!uploadData.resourceName.trim()) {
      ElMessage.warning('请输入资源名称');
      return;
  }
  if (!uploadData.file) {
      ElMessage.warning('请选择要上传的文件');
      return;
  }

  uploading.value = true;

  // 1. 创建 FormData 对象
  const formData = new FormData();
  formData.append('file', uploadData.file);
  formData.append('resourceName', uploadData.resourceName);
  formData.append('type', uploadData.type);

  // 2. 调用 store 中的 action
  await courseStore.uploadResource(
      props.courseId,
      formData,
      () => {
          // 成功回调：清空表单，方便用户继续上传下一个
          resetUploadForm();
          ElMessage.success('上传成功，列表已更新！');
      }
  );

  uploading.value = false;
};

// 定义暴露给父组件的方法
const open = () => {
  dialogVisible.value = true;
};

defineExpose({
  open,
});
</script>

<style scoped>
.upload-section {
  margin-bottom: 20px;
}

.upload-form .el-row {
  align-items: center;
}

.upload-buttons {
  display: flex;
  gap: 10px;
}

.file-tip {
  margin-top: 10px;
  font-size: 12px;
  color: #909399;
}

canvas {
  /* ✅ 修改：不再强制宽度100%，让它自然伸缩 */
  /* width: 100%; */
  border-radius: 6px;
  border: 1px solid #e4e7ed;
  background-color: #fff;
  display: block;
  margin: 0 auto;
}
.thumbnail-canvas {
  width: 100%; /* 强制缩略图宽度撑满其容器，保持原有比例 */
  margin-top: 6px; /* 保留上边距 */
}
/* ✅ 新增：PDF预览容器的样式 */
.pdf-container {
  width: 100%;
  height: 75vh; /* 设置一个视口高度，可以根据需要调整 */
  overflow: auto; /* 当内容超出时显示滚动条 */
  background-color: #f5f7fa; /* 设置背景色以区分 */
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  cursor: grab; /* 默认显示可抓取手势 */
  text-align: center; /* 确保画布在容器内水平居中 */
}

/* 当拖动时，显示正在抓取的手势 */
.pdf-container:active {
  cursor: grabbing;
}


.resource-card {
  margin-bottom: 16px;
}

.resource-card .el-icon {
  vertical-align: middle;
  margin-right: 5px;
}
</style>